/*
 * @(#)FileFilter.java	0.1.0 2011/04/01
 *
 * Created by (C) Convergence Square. Inc., All rights reserved.
 */
package com.oniontech.stamptour.common.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import com.oniontech.stamptour.common.lang.LOG;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;

// TODO: Auto-generated Javadoc
/**
 * ���� IO ó���� ����Ѵ�. 1. Asset ����� ���� �Ǵ� ����� Device ��ġ�� �����Ѵ�.
 * 
 * @author jinchulkim
 * @version 0.1.0 2011/04/01
 * @since 2011/04/01
 * 
 */

public final class FileFilter
{

	/**
	 * ��� �� ������ �����ϴ��� ������ üũ�Ѵ�.
	 * 
	 * @param makeDir
	 *            ���丮 �� ����.
	 * @param path
	 *            üũ�� Path
	 * @return ���� ����.
	 */
	public static boolean checkPath(boolean makeDir, String path)
	{
		File dirPath = new File(path);
		if (makeDir && !dirPath.exists())
		{
			LOG.Log_DEV("FileFilter", "Create Directory Path : " + path);
			dirPath.mkdirs();
			return false;
		}
		return dirPath.exists();
	}

	/**
	 * ������ �����Ѵ�.
	 * 
	 * @param isNew
	 *            ���� �ű� ����.
	 * @param from
	 *            ����� InputStream ��ü.
	 * @param tarPath
	 *            ������ File Path
	 * @throws FileNotFoundException
	 *             the file not found exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	private static void doFileCopy(boolean isNew, InputStream from,
			String tarPath) throws FileNotFoundException, IOException
	{
		if (checkPath(false, tarPath))
		{
			LOG.Log_DEV("FileFilter", tarPath + " is Exist~~~~");
			return;
		}

		File tarFile = new File(tarPath);
		OutputStream out = new FileOutputStream(tarFile);
		int fileSize = from.available();
		byte[] buff = new byte[fileSize];
		LOG.Log_DEV("FileFilter", "File : " + tarPath + ", Memory : "
				+ fileSize + "byte");
		int len, start = 0;
		while ((len = from.read(buff)) > 0)
		{
			out.write(buff, start, len);
			start = len;
		}
		out.flush();
		out.close();
		out = null;
		buff = null;
		tarFile = null;
	}

	/**
	 * Asset ������� ������ ���� ������ Device��ġ�� �����Ѵ�.
	 * 
	 * @param assetMgr
	 *            AssetManager ��ü.
	 * @param fromPath
	 *            Asset ��� File Path
	 * @param toPath
	 *            ������ Path.
	 * @param fileName
	 *            ������ File �̸�.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void copyFromAssetsFileToSdCard(AssetManager assetMgr,
			String fromPath, String toPath, String fileName) throws IOException
	{
		// check dir
		boolean isNew = checkPath(true, toPath);

		InputStream in = assetMgr.open(fromPath);
		doFileCopy(isNew, in, toPath + fileName);
		in.close();
		in = null;
	}

	/**
	 * Asset ������� ������ ��� ������ Device��ġ�� �����Ѵ�.
	 * 
	 * @param assetMgr
	 *            AssetManaer ��ü.
	 * @param fromPath
	 *            Asset ��� ���.
	 * @param toPath
	 *            ������ ��� ���.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void copyFromAssetsFolderToSdCard(AssetManager assetMgr,
			String fromPath, String toPath) throws IOException
	{
		// check dir
		boolean isNew = checkPath(true, toPath);

		String[] fileList = assetMgr.list(fromPath);
		LOG.Log_DEV("FileFilter", " file lenth : " + fileList.length);
		for (int i = 0; i < fileList.length; i++)
		{
			doFileCopy(isNew, assetMgr.open(fromPath + "/" + fileList[i]),
					toPath + fileList[i]);
		}
	}

	/**
	 * Asset�� �����ϴ� ������ InputStream��ü�� ��´�.
	 * 
	 * @param assetMgr
	 *            AssetManager ��ü.
	 * @param filePath
	 *            ���� ���.
	 * @return ������ InputStream ��ü.
	 */
	public static InputStream getAssetsFileInputStream(AssetManager assetMgr,
			String filePath)
	{
		try
		{
			return assetMgr.open(filePath);
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			System.out.println("예외 발생");
		}
		return null;
	}

	/**
	 * ��Ʈ��ũ ������ ũ�� �� �� ������ Byte �迭�� ��´�.
	 * 
	 * @param size
	 *            ���� ���� size
	 * @param in
	 *            ���� InputStream��ü.
	 * @return byte �迭.
	 */
	public static byte[] checkNetworkFileSize(int size, InputStream in)
	{
		byte[] fileBuffer = getFileBuffer(in);
		if (fileBuffer.length == size)
		{
			return fileBuffer;
		}
		return null;
	}

	/**
	 * InputStream ��ü���� byte �迭�� ��´�.
	 * 
	 * @param in
	 *            InputStream��ü.
	 * @return byte �迭.
	 */
	public static byte[] getFileBuffer(InputStream in)
	{
		byte[] fileBuffer = null;
		try
		{
			int end;
			byte[] buff = new byte[1024 * 25];
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			while ((end = in.read(buff)) > 0)
			{
				baos.write(buff, 0, end);
			}
			fileBuffer = baos.toByteArray();
			baos.flush();
			baos.close();
			return fileBuffer;
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			System.out.println("예외 발생");
		}
		return null;
	}

	/**
	 * ��Ʈ��ũ�� �����ϴ� ������ �����Ѵ�.
	 * 
	 * @param inbuff
	 *            ������ byte �迭.
	 * @param toPath
	 *            ������ ���.
	 * @param fileName
	 *            ���� �̸�.
	 * @throws FileNotFoundException
	 *             the file not found exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void copyFromNetworkFileToSdCard(byte[] inbuff,
			String toPath, String fileName) throws FileNotFoundException,
			IOException
	{
		File tarPath = new File(toPath);
		if (!tarPath.exists())
		{
			tarPath.mkdirs();
		}

		File tarFile = new File(toPath + fileName);
		FileOutputStream out = new FileOutputStream(tarFile);
		out.write(inbuff);
		out.flush();
		out.close();

	}

	/**
	 * �ش� ������ ������ ��´�.
	 * 
	 * @param filePath
	 *            ���� ���.
	 * @return ���ϳ���.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static String[] getFileContent(String filePath) throws IOException
	{
		ArrayList<String> list = new ArrayList<String>();
		BufferedReader br = new BufferedReader(new FileReader(filePath));
		String text;
		while ((text = br.readLine()) != null)
		{
			list.add(text);
		}
		String[] file = new String[list.size()];
		list.toArray(file);
		br.close();
		return file;
	}

	/**
	 * �ش� InputStream ��ü�� ������ ��´�.
	 * 
	 * @param input
	 *            InputStream ��ü.
	 * @return ���� ����.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static String[] getFileContent(InputStream input) throws IOException
	{
		ArrayList<String> list = new ArrayList<String>();
		BufferedReader br = new BufferedReader(new InputStreamReader(input));
		String text;
		while ((text = br.readLine()) != null)
		{
			list.add(text);
		}
		String[] file = new String[list.size()];
		list.toArray(file);
		br.close();
		return file;
	}

	/**
	 * Ư�����Ͽ� ������ �����Ѵ�.
	 * 
	 * @param filePath
	 *            ������ ���� ���.
	 * @param content
	 *            ������ ����.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void writeFileContent(String filePath, String[] content)
			throws IOException
	{
		BufferedWriter bw = new BufferedWriter(new FileWriter(filePath));
		for (int i = 0, n = content.length; i < n; i++)
		{
			bw.write(content[i]);
			bw.newLine();
		}
		bw.flush();
		bw.close();
	}

	/**
	 * ��Ʈ��ũ�� �ִ� ������ ������ ��´�.
	 * 
	 * @param urlPath
	 *            ������ URL����.
	 * @return �������� ��ü.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static NetworkFileData networkFileLoad(String urlPath)
			throws IOException
	{
		URL url = new URL(urlPath);
		URLConnection urlCon = url.openConnection();
		urlCon.connect();

		NetworkFileData data = new NetworkFileData();
		data.inputStream = new InputStream[1];
		data.inputStream[0] = urlCon.getInputStream();
		data.size = urlCon.getContentLength();
		return data;
	}

	/**
	 * ��Ʈ��ũ�� �����ϴ� ������ InputStream�� ��´�.
	 * 
	 * @param urlPath
	 *            ������ URL����.
	 * @return InputStream��ü.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	private static InputStream getInputStream(String urlPath)
			throws IOException
	{
		URL url;
		LOG.Log_DEV("FileFilter", "URL_PATH : " + urlPath);
		url = new URL(urlPath);

		URLConnection urlCon = url.openConnection();
		urlCon.connect();
		return urlCon.getInputStream();
	}

	/**
	 * ������ �����Ѵ�.
	 * 
	 * @param input
	 *            ������ InputStream��ü.
	 * @param path
	 *            ������ ���.
	 * @param name
	 *            �������� �̸�.
	 * @param listener
	 *            ������¸� ǥ���ϱ� ���� Listener��ü.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void saveFile(InputStream input, String path, String name,
			FileSaveStateListener listener) throws IOException
	{
		checkPath(true, path);
		SharedPreperenceUtil.getInstance().setStringValue("FAILLIST",
				"SAVEFILE", path + name);
		int writeSize = 0;
		FileOutputStream output = new FileOutputStream(new File(path + name));
		byte[] buffer = new byte[1024 * 4];
		while ((writeSize = input.read(buffer)) > 0)
		{
			output.write(buffer, 0, writeSize);
			if (listener != null)
				listener.updateState(FileSaveStateListener.WRITING, writeSize);
		}
		LOG.Log_DEV("FileFilter", "Save Complete file path = " + path + name);
		SharedPreperenceUtil.getInstance().setStringValue("FAILLIST",
				"SAVEFILE", "");
		if (listener != null)
			listener.updateState(FileSaveStateListener.END, writeSize);
		input.close();
		output.flush();
		output.close();
	}

	/**
	 * ������ �����Ѵ�.
	 * 
	 * @param url
	 *            ������ ���� url����.
	 * @param path
	 *            ������ ���.
	 * @param name
	 *            ������ ���� �̸�.
	 * @param listener
	 *            ������¸� �˷��ֱ����� Listener��ü.
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static void saveFile(String url, String path, String name,
			FileSaveStateListener listener) throws IOException
	{
		System.out.println("++++++++++++++++DownloadURL++++ //" + url);
		checkPath(true, path);
		InputStream input = getInputStream(url);
		FileOutputStream output = new FileOutputStream(new File(path + name));
		int writeSize = 0;
		byte[] buffer = new byte[1024 * 4];
		while ((writeSize = input.read(buffer)) > 0)
		{
			output.write(buffer, 0, writeSize);
			if (listener != null)
				listener.updateState(FileSaveStateListener.WRITING, writeSize);
		}
		input.close();
		output.flush();
		output.close();
		output = null;
		input = null;
		if (listener != null)
			listener.updateState(FileSaveStateListener.END, writeSize);
	}

	/**
	 * �ش� ����� ���� �̸� ����Ʈ�� ��´�.
	 * 
	 * @param path
	 *            ���� ��� ���.
	 * @return �����̸� ����Ʈ �迭.
	 */
	public static String[] getFileList(String path)
	{
		File file = new File(path);

		return file.list();
	}

	/**
	 * �ش� ������ �����.
	 * 
	 * @param path
	 *            ���� ������ ���.
	 * @return ���� ���� ����.
	 */
	public static boolean fileDelete(String path)
	{
		LOG.Log_DEV("FileFilter", "File Delete path : " + path);
		return new File(path).delete();
	}

	/**
	 * �ش� ����� ������� ������ �����.
	 * 
	 * @param path
	 *            ���� ��� ���.
	 */
	public static void deleteDir(String path)
	{
		File filePath = new File(path);
		if (!filePath.exists())
			return;
		File[] files = filePath.listFiles();
		for (int i = 0, n = files.length; i < n; i++)
		{
			files[i].delete();
		}
		filePath.delete();
	}

	/**
	 * Bitmap�� ���Ϸ� �����Ѵ�.
	 * 
	 * @param map
	 *            ������ Bitmap��ü.
	 * @param filePath
	 *            ������ ���.
	 * @param fileName
	 *            ������ ���� �̸�.
	 */
	public static void saveScreenShot(Bitmap map, String filePath,
			String fileName)
	{
		checkPath(true, filePath);
		try
		{
			FileOutputStream fileOut = new FileOutputStream(new File(filePath
					+ fileName));
			map.compress(CompressFormat.JPEG, 70, fileOut);
			fileOut.flush();
			fileOut.close();
		} catch (FileNotFoundException e)
		{
			System.out.println("예외 발생");
		} catch (IOException e)
		{
			System.out.println("예외 발생");
		}
	}

	/**
	 * ���� ���� ���¸� �˷��ֱ����� Interface class.
	 * 
	 * @author jinchulkim
	 */
	public interface FileSaveStateListener
	{
		/**
		 * ���� ���� ���¸� �˷��ش�.
		 * 
		 * @param state
		 *            ���� �������.
		 * @param size
		 *            ������ ������ size
		 */
		public void updateState(int state, int size);

		/** ���� ������� Index ������ ���� ����. */
		public static final int WRITING = 0;

		/** ���� ������� Index ����Ϸ� ���� ����. */
		public static final int END = 1;
	}

	/**
	 * ��Ʈ��ũ ���� ������ �����Ѵ�.
	 * 
	 * @author jinchulkim
	 * 
	 */
	public static final class NetworkFileData
	{

		/** ��Ʈ��ũ ������ InputStream ��ü ����. */
		public InputStream[] inputStream;

		/** ��Ʈ��ũ ������ ũ�Ⱚ ����. */
		public int size;

		/**
		 * Ŭ���� ������ �޸𸮸� ȯ���Ѵ�.
		 */
		public void dispose()
		{
			try
			{
				for (int i = 0; i < inputStream.length; i++)
				{
					inputStream[i].close();
				}
				inputStream = null;
			} catch (IOException e)
			{
				System.out.println("예외 발생");
			}
		}
	}

	/**
	 * Network file load.
	 * 
	 * @param urlPath
	 *            the url path
	 * @return the network file data
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static NetworkFileData networkFileLoad(String[] urlPath)
			throws IOException
	{
		NetworkFileData data = new NetworkFileData();
		data.inputStream = new InputStream[urlPath.length];
		for (int i = 0, n = urlPath.length; i < n; i++)
		{
			URL url = new URL(urlPath[i]);
			URLConnection urlCon = url.openConnection();
			urlCon.connect();
			data.inputStream[i] = urlCon.getInputStream();
			data.size += urlCon.getContentLength();
		}
		return data;
	}
}
